package com.uwo.commons.redis.configuration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Map;

/**
 * Created by yanhao on 2018/2/4.
 */
@Component
public class RedisHelper {

    private final Logger log = LoggerFactory.getLogger(RedisHelper.class);

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RedisProperties redisProperties;

    protected void select(int index){
        JedisConnectionFactory redisConnectionFactory = new JedisConnectionFactory();
        redisConnectionFactory.setHostName(redisProperties.getHost());
        redisConnectionFactory.setPort(redisProperties.getPort());
        redisConnectionFactory.setDatabase(index);
        redisConnectionFactory.afterPropertiesSet();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
    }

    public byte[] bucketId(String key){
        try {
            return getBucketId(key.getBytes("UTF-8"), redisProperties.getBit());
        }catch (Exception e){
            return new byte[redisProperties.getBit()];
        }

    }

    public void saveHash(byte[] bucketId, String key, Object value){
        log.info("key = {}, value = {}", bucketId, value);
        redisTemplate.boundHashOps(new String(bucketId)).put(key, value);
    }

    public void saveHash(byte[] bucketId,  Map<String, Object> values){
        log.info("key = {}, value = {}", bucketId, values);
        redisTemplate.boundHashOps(bucketId).putAll(values);
    }

    public Object getHash(byte[] bucketId, String key){
        log.info("bucketId = {}, key = {}", bucketId, key);
        return redisTemplate.boundHashOps(new String(bucketId)).get(key);
    }

    public List<?> getHash(byte[] bucketId){
        log.info("bucketId = {}", bucketId);
        return redisTemplate.boundHashOps(new String(bucketId)).values();
    }

    public void removeHash(byte[] bucketId, String key){
        redisTemplate.boundHashOps(new String(bucketId)).delete(key);
    }

    private byte[] getBucketId(byte [] key, Integer bit) throws NoSuchAlgorithmException {
        MessageDigest mdInst = MessageDigest.getInstance("MD5");
        mdInst.update(key);
        byte [] md = mdInst.digest();
        byte [] r = new byte[(bit-1)/7 + 1];// 因为一个字节中只有7位能够表示成单字符
        int a = (int) Math.pow(2, bit%7)-2;
        md[r.length-1] = (byte) (md[r.length-1] & a);
        System.arraycopy(md, 0, r, 0, r.length);
        for(int i=0;i<r.length;i++) {
            if(r[i]<0) r[i] &= 127;
        }
        return r;
    }




}
